#ifndef _TIME_VALUE_H_
#define _TIME_VALUE_H_

#include "netfwd.h"

time_t const ONE_SECOND_IN_USECS = 1000000;

typedef struct timespec timespec_t;

class Time_Value
{
public:
    /* Constant zero */
    static const Time_Value zero;

    Time_Value();

    explicit Time_Value( time_t sec, time_t usec = 0 );

    explicit Time_Value( const struct timeval & tv );

    void set( time_t sec, time_t usec );

    void set( const struct timeval & tv );

    time_t sec() const;

    void sec( time_t sec );

    time_t usec() const;

    void usec( time_t usec );

    Time_Value & operator += ( const Time_Value & tv );

    Time_Value & operator += ( time_t t );

    Time_Value & operator = ( const Time_Value & tv );

    Time_Value & operator = ( time_t t );

    Time_Value & operator -= ( const Time_Value & tv );

    Time_Value & operator -= ( time_t t );

    operator timespec_t() const;

    static Time_Value timeofday();

    static const char * time_name( time_t t );

    static const char * curr_time_name();

    static uint64_t rdtsc();

    static uint64_t now_us();

    static uint64_t now_ms();

    friend inline bool operator > ( const Time_Value & left, const Time_Value & right )
    {
        if( left.m_tv.tv_sec == right.m_tv.tv_sec )
            return left.m_tv.tv_usec > right.m_tv.tv_usec;
        return left.m_tv.tv_sec > right.m_tv.tv_sec;
    }

    friend inline Time_Value operator + ( const Time_Value & left, const Time_Value & right )
    {
        Time_Value temp = left;
        temp += right;
        return temp;
    }

    friend inline Time_Value operator - ( const Time_Value & left, const Time_Value & right )
    {
        Time_Value temp = left;
        temp -= right;
        return temp;
    }

    friend inline bool operator == ( const Time_Value & left, const Time_Value & right )
    {
        return ( left.m_tv.tv_sec == right.m_tv.tv_sec &&
                 left.m_tv.tv_usec == right.m_tv.tv_usec );
    }

private:
    void normalize();

    struct timeval  m_tv;
};

class TimeClock
{
public:
    TimeClock();

    uint64_t clock_now_ms();

    Time_Value get_timeval();
private:
    uint64_t    m_last_tsc;
    uint64_t    m_last_time;
};

#endif // _TIME_VALUE_H_

